﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;


namespace harfbuzz
{
    public struct hb_buffer_t
    {
        public IntPtr handle;
    }
    public enum hb_direction_t
    {
        HB_DIRECTION_INVALID = 0,
        HB_DIRECTION_LTR = 4,
        HB_DIRECTION_RTL,
        HB_DIRECTION_TTB,
        HB_DIRECTION_BTT
    }

    public struct hb_script_t
    {
        public uint value;
        public static hb_script_t HB_TAG(char c1, char c2, char c3, char c4)
        {
            var v = ((c1 & 0xFF) << 24) | ((c2 & 0xff) << 16) | ((c3 & 0xFF) << 8) | (c4 & 0xFF);
            return new hb_script_t() { value = (uint)v };
        }
        public static hb_script_t HB_TAG(byte c1, byte c2, byte c3, byte c4)
        {
            var v = ((c1 & 0xFF) << 24) | ((c2 & 0xff) << 16) | ((c3 & 0xFF) << 8) | (c4 & 0xFF);
            return new hb_script_t() { value = (uint)v };
        }
        public readonly static hb_script_t HB_SCRIPT_COMMON = HB_TAG('Z', 'y', 'y', 'y'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_INHERITED = HB_TAG('Z', 'i', 'n', 'h'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_UNKNOWN = HB_TAG('Z', 'z', 'z', 'z'); /*5.0*/

        public readonly static hb_script_t HB_SCRIPT_ARABIC = HB_TAG('A', 'r', 'a', 'b'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_ARMENIAN = HB_TAG('A', 'r', 'm', 'n'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_BENGALI = HB_TAG('B', 'e', 'n', 'g'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_CYRILLIC = HB_TAG('C', 'y', 'r', 'l'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_DEVANAGARI = HB_TAG('D', 'e', 'v', 'a'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_GEORGIAN = HB_TAG('G', 'e', 'o', 'r'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_GREEK = HB_TAG('G', 'r', 'e', 'k'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_GUJARATI = HB_TAG('G', 'u', 'j', 'r'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_GURMUKHI = HB_TAG('G', 'u', 'r', 'u'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_HANGUL = HB_TAG('H', 'a', 'n', 'g'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_HAN = HB_TAG('H', 'a', 'n', 'i'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_HEBREW = HB_TAG('H', 'e', 'b', 'r'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_HIRAGANA = HB_TAG('H', 'i', 'r', 'a'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_KANNADA = HB_TAG('K', 'n', 'd', 'a'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_KATAKANA = HB_TAG('K', 'a', 'n', 'a'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_LAO = HB_TAG('L', 'a', 'o', 'o'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_LATIN = HB_TAG('L', 'a', 't', 'n'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_MALAYALAM = HB_TAG('M', 'l', 'y', 'm'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_ORIYA = HB_TAG('O', 'r', 'y', 'a'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_TAMIL = HB_TAG('T', 'a', 'm', 'l'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_TELUGU = HB_TAG('T', 'e', 'l', 'u'); /*1.1*/
        public readonly static hb_script_t HB_SCRIPT_THAI = HB_TAG('T', 'h', 'a', 'i'); /*1.1*/

        public readonly static hb_script_t HB_SCRIPT_TIBETAN = HB_TAG('T', 'i', 'b', 't'); /*2.0*/

        public readonly static hb_script_t HB_SCRIPT_BOPOMOFO = HB_TAG('B', 'o', 'p', 'o'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_BRAILLE = HB_TAG('B', 'r', 'a', 'i'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG('C', 'a', 'n', 's'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_CHEROKEE = HB_TAG('C', 'h', 'e', 'r');/*3.0*/
        public readonly static hb_script_t HB_SCRIPT_ETHIOPIC = HB_TAG('E', 't', 'h', 'i'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_KHMER = HB_TAG('K', 'h', 'm', 'r'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_MONGOLIAN = HB_TAG('M', 'o', 'n', 'g'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_MYANMAR = HB_TAG('M', 'y', 'm', 'r'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_OGHAM = HB_TAG('O', 'g', 'a', 'm'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_RUNIC = HB_TAG('R', 'u', 'n', 'r'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_SINHALA = HB_TAG('S', 'i', 'n', 'h'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_SYRIAC = HB_TAG('S', 'y', 'r', 'c'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_THAANA = HB_TAG('T', 'h', 'a', 'a'); /*3.0*/
        public readonly static hb_script_t HB_SCRIPT_YI = HB_TAG('Y', 'i', 'i', 'i'); /*3.0*/

        public readonly static hb_script_t HB_SCRIPT_DESERET = HB_TAG('D', 's', 'r', 't'); /*3.1*/
        public readonly static hb_script_t HB_SCRIPT_GOTHIC = HB_TAG('G', 'o', 't', 'h'); /*3.1*/
        public readonly static hb_script_t HB_SCRIPT_OLD_ITALIC = HB_TAG('I', 't', 'a', 'l'); /*3.1*/

        public readonly static hb_script_t HB_SCRIPT_BUHID = HB_TAG('B', 'u', 'h', 'd'); /*3.2*/
        public readonly static hb_script_t HB_SCRIPT_HANUNOO = HB_TAG('H', 'a', 'n', 'o'); /*3.2*/
        public readonly static hb_script_t HB_SCRIPT_TAGALOG = HB_TAG('T', 'g', 'l', 'g'); /*3.2*/
        public readonly static hb_script_t HB_SCRIPT_TAGBANWA = HB_TAG('T', 'a', 'g', 'b'); /*3.2*/

        public readonly static hb_script_t HB_SCRIPT_CYPRIOT = HB_TAG('C', 'p', 'r', 't'); /*4.0*/
        public readonly static hb_script_t HB_SCRIPT_LIMBU = HB_TAG('L', 'i', 'm', 'b'); /*4.0*/
        public readonly static hb_script_t HB_SCRIPT_LINEAR_B = HB_TAG('L', 'i', 'n', 'b'); /*4.0*/
        public readonly static hb_script_t HB_SCRIPT_OSMANYA = HB_TAG('O', 's', 'm', 'a'); /*4.0*/
        public readonly static hb_script_t HB_SCRIPT_SHAVIAN = HB_TAG('S', 'h', 'a', 'w'); /*4.0*/
        public readonly static hb_script_t HB_SCRIPT_TAI_LE = HB_TAG('T', 'a', 'l', 'e'); /*4.0*/
        public readonly static hb_script_t HB_SCRIPT_UGARITIC = HB_TAG('U', 'g', 'a', 'r'); /*4.0*/

        public readonly static hb_script_t HB_SCRIPT_BUGINESE = HB_TAG('B', 'u', 'g', 'i'); /*4.1*/
        public readonly static hb_script_t HB_SCRIPT_COPTIC = HB_TAG('C', 'o', 'p', 't'); /*4.1*/
        public readonly static hb_script_t HB_SCRIPT_GLAGOLITIC = HB_TAG('G', 'l', 'a', 'g'); /*4.1*/
        public readonly static hb_script_t HB_SCRIPT_KHAROSHTHI = HB_TAG('K', 'h', 'a', 'r'); /*4.1*/
        public readonly static hb_script_t HB_SCRIPT_NEW_TAI_LUE = HB_TAG('T', 'a', 'l', 'u'); /*4.1*/
        public readonly static hb_script_t HB_SCRIPT_OLD_PERSIAN = HB_TAG('X', 'p', 'e', 'o'); /*4.1*/
        public readonly static hb_script_t HB_SCRIPT_SYLOTI_NAGRI = HB_TAG('S', 'y', 'l', 'o'); /*4.1*/
        public readonly static hb_script_t HB_SCRIPT_TIFINAGH = HB_TAG('T', 'f', 'n', 'g'); /*4.1*/

        public readonly static hb_script_t HB_SCRIPT_BALINESE = HB_TAG('B', 'a', 'l', 'i'); /*5.0*/
        public readonly static hb_script_t HB_SCRIPT_CUNEIFORM = HB_TAG('X', 's', 'u', 'x'); /*5.0*/
        public readonly static hb_script_t HB_SCRIPT_NKO = HB_TAG('N', 'k', 'o', 'o'); /*5.0*/
        public readonly static hb_script_t HB_SCRIPT_PHAGS_PA = HB_TAG('P', 'h', 'a', 'g'); /*5.0*/
        public readonly static hb_script_t HB_SCRIPT_PHOENICIAN = HB_TAG('P', 'h', 'n', 'x'); /*5.0*/

        public readonly static hb_script_t HB_SCRIPT_CARIAN = HB_TAG('C', 'a', 'r', 'i'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_CHAM = HB_TAG('C', 'h', 'a', 'm'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_KAYAH_LI = HB_TAG('K', 'a', 'l', 'i'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_LEPCHA = HB_TAG('L', 'e', 'p', 'c'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_LYCIAN = HB_TAG('L', 'y', 'c', 'i'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_LYDIAN = HB_TAG('L', 'y', 'd', 'i'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_OL_CHIKI = HB_TAG('O', 'l', 'c', 'k'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_REJANG = HB_TAG('R', 'j', 'n', 'g'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_SAURASHTRA = HB_TAG('S', 'a', 'u', 'r'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_SUNDANESE = HB_TAG('S', 'u', 'n', 'd'); /*5.1*/
        public readonly static hb_script_t HB_SCRIPT_VAI = HB_TAG('V', 'a', 'i', 'i'); /*5.1*/

        public readonly static hb_script_t HB_SCRIPT_AVESTAN = HB_TAG('A', 'v', 's', 't'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_BAMUM = HB_TAG('B', 'a', 'm', 'u'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG('E', 'g', 'y', 'p'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG('A', 'r', 'm', 'i'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG('P', 'h', 'l', 'i'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG('P', 'r', 't', 'i'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_JAVANESE = HB_TAG('J', 'a', 'v', 'a'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_KAITHI = HB_TAG('K', 't', 'h', 'i'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_LISU = HB_TAG('L', 'i', 's', 'u'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_MEETEI_MAYEK = HB_TAG('M', 't', 'e', 'i'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG('S', 'a', 'r', 'b'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_OLD_TURKIC = HB_TAG('O', 'r', 'k', 'h'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_SAMARITAN = HB_TAG('S', 'a', 'm', 'r'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_TAI_THAM = HB_TAG('L', 'a', 'n', 'a'); /*5.2*/
        public readonly static hb_script_t HB_SCRIPT_TAI_VIET = HB_TAG('T', 'a', 'v', 't'); /*5.2*/

        public readonly static hb_script_t HB_SCRIPT_BATAK = HB_TAG('B', 'a', 't', 'k'); /*6.0*/
        public readonly static hb_script_t HB_SCRIPT_BRAHMI = HB_TAG('B', 'r', 'a', 'h'); /*6.0*/
        public readonly static hb_script_t HB_SCRIPT_MANDAIC = HB_TAG('M', 'a', 'n', 'd'); /*6.0*/

        public readonly static hb_script_t HB_SCRIPT_CHAKMA = HB_TAG('C', 'a', 'k', 'm'); /*6.1*/
        public readonly static hb_script_t HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG('M', 'e', 'r', 'c'); /*6.1*/
        public readonly static hb_script_t HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG('M', 'e', 'r', 'o'); /*6.1*/
        public readonly static hb_script_t HB_SCRIPT_MIAO = HB_TAG('P', 'l', 'r', 'd'); /*6.1*/
        public readonly static hb_script_t HB_SCRIPT_SHARADA = HB_TAG('S', 'h', 'r', 'd'); /*6.1*/
        public readonly static hb_script_t HB_SCRIPT_SORA_SOMPENG = HB_TAG('S', 'o', 'r', 'a'); /*6.1*/
        public readonly static hb_script_t HB_SCRIPT_TAKRI = HB_TAG('T', 'a', 'k', 'r'); /*6.1*/

        /*
         * Since: 0.9.30
         */
        public readonly static hb_script_t HB_SCRIPT_BASSA_VAH = HB_TAG('B', 'a', 's', 's'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG('A', 'g', 'h', 'b'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_DUPLOYAN = HB_TAG('D', 'u', 'p', 'l'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_ELBASAN = HB_TAG('E', 'l', 'b', 'a'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_GRANTHA = HB_TAG('G', 'r', 'a', 'n'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_KHOJKI = HB_TAG('K', 'h', 'o', 'j'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_KHUDAWADI = HB_TAG('S', 'i', 'n', 'd'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_LINEAR_A = HB_TAG('L', 'i', 'n', 'a'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_MAHAJANI = HB_TAG('M', 'a', 'h', 'j'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_MANICHAEAN = HB_TAG('M', 'a', 'n', 'i'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_MENDE_KIKAKUI = HB_TAG('M', 'e', 'n', 'd'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_MODI = HB_TAG('M', 'o', 'd', 'i'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_MRO = HB_TAG('M', 'r', 'o', 'o'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_NABATAEAN = HB_TAG('N', 'b', 'a', 't'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG('N', 'a', 'r', 'b'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_OLD_PERMIC = HB_TAG('P', 'e', 'r', 'm'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_PAHAWH_HMONG = HB_TAG('H', 'm', 'n', 'g'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_PALMYRENE = HB_TAG('P', 'a', 'l', 'm'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_PAU_CIN_HAU = HB_TAG('P', 'a', 'u', 'c'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG('P', 'h', 'l', 'p'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_SIDDHAM = HB_TAG('S', 'i', 'd', 'd'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_TIRHUTA = HB_TAG('T', 'i', 'r', 'h'); /*7.0*/
        public readonly static hb_script_t HB_SCRIPT_WARANG_CITI = HB_TAG('W', 'a', 'r', 'a'); /*7.0*/

        public readonly static hb_script_t HB_SCRIPT_AHOM = HB_TAG('A', 'h', 'o', 'm'); /*8.0*/
        public readonly static hb_script_t HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG('H', 'l', 'u', 'w'); /*8.0*/
        public readonly static hb_script_t HB_SCRIPT_HATRAN = HB_TAG('H', 'a', 't', 'r'); /*8.0*/
        public readonly static hb_script_t HB_SCRIPT_MULTANI = HB_TAG('M', 'u', 'l', 't'); /*8.0*/
        public readonly static hb_script_t HB_SCRIPT_OLD_HUNGARIAN = HB_TAG('H', 'u', 'n', 'g'); /*8.0*/
        public readonly static hb_script_t HB_SCRIPT_SIGNWRITING = HB_TAG('S', 'g', 'n', 'w'); /*8.0*/

        /*
         * Since 1.3.0
         */
        public readonly static hb_script_t HB_SCRIPT_ADLAM = HB_TAG('A', 'd', 'l', 'm'); /*9.0*/
        public readonly static hb_script_t HB_SCRIPT_BHAIKSUKI = HB_TAG('B', 'h', 'k', 's'); /*9.0*/
        public readonly static hb_script_t HB_SCRIPT_MARCHEN = HB_TAG('M', 'a', 'r', 'c'); /*9.0*/
        public readonly static hb_script_t HB_SCRIPT_OSAGE = HB_TAG('O', 's', 'g', 'e'); /*9.0*/
        public readonly static hb_script_t HB_SCRIPT_TANGUT = HB_TAG('T', 'a', 'n', 'g'); /*9.0*/
        public readonly static hb_script_t HB_SCRIPT_NEWA = HB_TAG('N', 'e', 'w', 'a'); /*9.0*/

        /*
         * Since 1.6.0
         */
        public readonly static hb_script_t HB_SCRIPT_MASARAM_GONDI = HB_TAG('G', 'o', 'n', 'm'); /*10.0*/
        public readonly static hb_script_t HB_SCRIPT_NUSHU = HB_TAG('N', 's', 'h', 'u'); /*10.0*/
        public readonly static hb_script_t HB_SCRIPT_SOYOMBO = HB_TAG('S', 'o', 'y', 'o'); /*10.0*/
        public readonly static hb_script_t HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG('Z', 'a', 'n', 'b'); /*10.0*/

        /*
         * Since 1.8.0
         */
        public readonly static hb_script_t HB_SCRIPT_DOGRA = HB_TAG('D', 'o', 'g', 'r'); /*11.0*/
        public readonly static hb_script_t HB_SCRIPT_GUNJALA_GONDI = HB_TAG('G', 'o', 'n', 'g'); /*11.0*/
        public readonly static hb_script_t HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG('R', 'o', 'h', 'g'); /*11.0*/
        public readonly static hb_script_t HB_SCRIPT_MAKASAR = HB_TAG('M', 'a', 'k', 'a'); /*11.0*/
        public readonly static hb_script_t HB_SCRIPT_MEDEFAIDRIN = HB_TAG('M', 'e', 'd', 'f'); /*11.0*/
        public readonly static hb_script_t HB_SCRIPT_OLD_SOGDIAN = HB_TAG('S', 'o', 'g', 'o'); /*11.0*/
        public readonly static hb_script_t HB_SCRIPT_SOGDIAN = HB_TAG('S', 'o', 'g', 'd'); /*11.0*/

        /*
         * Since 2.4.0
         */
        public readonly static hb_script_t HB_SCRIPT_ELYMAIC = HB_TAG('E', 'l', 'y', 'm'); /*12.0*/
        public readonly static hb_script_t HB_SCRIPT_NANDINAGARI = HB_TAG('N', 'a', 'n', 'd'); /*12.0*/
        public readonly static hb_script_t HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG('H', 'm', 'n', 'p'); /*12.0*/
        public readonly static hb_script_t HB_SCRIPT_WANCHO = HB_TAG('W', 'c', 'h', 'o'); /*12.0*/

        /*
         * Since 2.6.7
         */
        public readonly static hb_script_t HB_SCRIPT_CHORASMIAN = HB_TAG('C', 'h', 'r', 's'); /*13.0*/
        public readonly static hb_script_t HB_SCRIPT_DIVES_AKURU = HB_TAG('D', 'i', 'a', 'k'); /*13.0*/
        public readonly static hb_script_t HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG('K', 'i', 't', 's'); /*13.0*/
        public readonly static hb_script_t HB_SCRIPT_YEZIDI = HB_TAG('Y', 'e', 'z', 'i'); /*13.0*/

        /*
         * Since 3.0.0
         */
        public readonly static hb_script_t HB_SCRIPT_CYPRO_MINOAN = HB_TAG('C', 'p', 'm', 'n'); /*14.0*/
        public readonly static hb_script_t HB_SCRIPT_OLD_UYGHUR = HB_TAG('O', 'u', 'g', 'r'); /*14.0*/
        public readonly static hb_script_t HB_SCRIPT_TANGSA = HB_TAG('T', 'n', 's', 'a'); /*14.0*/
        public readonly static hb_script_t HB_SCRIPT_TOTO = HB_TAG('T', 'o', 't', 'o'); /*14.0*/
        public readonly static hb_script_t HB_SCRIPT_VITHKUQI = HB_TAG('V', 'i', 't', 'h'); /*14.0*/

        /* No script set. */
        public readonly static hb_script_t HB_SCRIPT_INVALID = HB_TAG(0, 0, 0, 0);

        /*< private >*/

        /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
         * without risking undefined behavior.  We have two, for historical reasons.
         * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed
         * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well.
         *
         * See this thread for technicalities:
         *
         *   https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
         */
        public readonly static hb_script_t _HB_SCRIPT_MAX_VALUE = HB_TAG(0x7f, 0xff, 0xff, 0xff);
        public readonly static hb_script_t _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG(0x7f, 0xff, 0xff, 0xff);

    }


    public struct hb_language_t
    {
        public IntPtr handle;
    }
    public struct hb_font_t
    {
        public IntPtr handle;
    }
    public struct hb_feature_t
    {
        public UInt32 tag;
        public UInt32 value;
        public UInt32 start;
        public UInt32 end;
    }
    public struct hb_blob_t
    { public IntPtr handle; }

    public struct hb_face_t
    { public IntPtr handle; }

    public struct hb_glyph_info_t
    {
        public UInt32 codepoint;
        /*< private >*/
        public UInt32 mask;
        /*< public >*/
        public UInt32 cluster;

        /*< private >*/
        public UInt32 var1;
        public UInt32 var2;
    }

    public struct hb_glyph_position_t
    {
        public int x_advance;
        public int y_advance;
        public int x_offset;
        public int y_offset;

        /*< private >*/
        public UInt32 var;
    }
    public enum hb_buffer_content_type_t
    {
        HB_BUFFER_CONTENT_TYPE_INVALID = 0,
        HB_BUFFER_CONTENT_TYPE_UNICODE,
        HB_BUFFER_CONTENT_TYPE_GLYPHS
    }

    static public class wrap
    {

        const string harfbuzz = "libharfbuzz-0";



        //1.Create a buffer and put your text in it.


        //hb_buffer_t* buf;
        //buf = hb_buffer_create();
        //hb_buffer_add_utf8(buf, text, -1, 0, -1);


        [DllImport(harfbuzz)]
        public static extern hb_buffer_t hb_buffer_create();
        [DllImport(harfbuzz)]
        static extern unsafe void hb_buffer_add_utf16(hb_buffer_t buf, char* text, int textlen, uint offset, int length);

        public static void hb_buffer_add_utf16(hb_buffer_t buf, string text)
        {
            unsafe
            {
                fixed (char* ptr = text)
                {
                    hb_buffer_add_utf16(buf, ptr, text.Length, 0, -1);
                }
            }
        }

        //2.Set the script, language and direction of the buffer.

        //      hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
        //hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
        //hb_buffer_set_language(buf, hb_language_from_string("en", -1));
        [DllImport(harfbuzz)]
        public static extern void hb_buffer_set_direction(hb_buffer_t buf, hb_direction_t HB_DIRECTION_LTR);

        [DllImport(harfbuzz)]
        public static extern void hb_buffer_set_script(hb_buffer_t buf, hb_script_t HB_SCRIPT_LATIN);

        [DllImport(harfbuzz)]
        public static extern void hb_buffer_set_language(hb_buffer_t buf, hb_language_t lang);

        [DllImport(harfbuzz)]
        private static extern unsafe hb_language_t hb_language_from_string(byte* text, int length);
        public static hb_language_t hb_language_from_string(string txt)
        {
            var bts = System.Text.Encoding.UTF8.GetBytes(txt);
            unsafe
            {
                fixed (byte* ptr = bts)
                {
                    return hb_language_from_string(ptr, bts.Length);
                }
            }
        }

        //3.Create a face and a font from a font file.

        //hb_blob_t* blob = hb_blob_create_from_file(filename); /* or hb_blob_create_from_file_or_fail() */
        //hb_face_t* face = hb_face_create(blob, 0);
        //hb_font_t* font = hb_font_create(face);
        public enum hb_memory_mode_t
        {
            HB_MEMORY_MODE_DUPLICATE,
            HB_MEMORY_MODE_READONLY,
            HB_MEMORY_MODE_WRITABLE,
            HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
        };


        [DllImport(harfbuzz)]
        private static extern unsafe hb_blob_t hb_blob_create(byte* data, uint length, hb_memory_mode_t mode, IntPtr user_Data, IntPtr destroy);

        [DllImport(harfbuzz)]
        private static extern unsafe hb_blob_t hb_blob_destory(hb_blob_t blob);

        [DllImport(harfbuzz)]
        private static extern unsafe hb_blob_t hb_blob_create_from_file(byte* text);
        public static hb_blob_t hb_blob_create_from_file(string text)
        {
            var bts = System.Text.Encoding.UTF8.GetBytes(text);
            unsafe
            {
                fixed (byte* ptr = bts)
                {
                    return hb_blob_create_from_file(ptr);
                }
            }
        }


        [DllImport(harfbuzz)]
        public static extern hb_face_t hb_face_create(hb_blob_t blob, uint index = 0);

        [DllImport(harfbuzz)]
        public static extern hb_face_t hb_ft_face_create_referenced(IntPtr ft_face);
        [DllImport(harfbuzz)]
        public static extern hb_font_t hb_ft_font_create_referenced(IntPtr ft_face);

        [DllImport(harfbuzz)]
        public static extern hb_font_t hb_font_create(hb_face_t face);
        //4.Shape!


        public static hb_font_t hb_font_create(byte[] data)
        {
            unsafe
            {
                fixed (byte* dataptr = data)
                {
                    var blob = hb_blob_create(dataptr, (uint)data.Length, hb_memory_mode_t.HB_MEMORY_MODE_READONLY, IntPtr.Zero, IntPtr.Zero);
                    var face = hb_face_create(blob, 0);
                    var font = hb_font_create(face);
                    return font;
                }
            }
        }
        //hb_shape(font, buf, NULL, 0);
        [DllImport(harfbuzz)]
        private static extern unsafe void hb_shape(hb_font_t font, hb_buffer_t buf, hb_feature_t* features, uint num_features);
        public static void hb_shape(hb_font_t font, hb_buffer_t buf)
        {
            unsafe
            {
                hb_shape(font, buf, null, 0);
            }
        }



        //5.Get the glyph and position information.

        //unsigned int glyph_count;
        //hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count);
        //hb_glyph_position_t* glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count);
        [DllImport(harfbuzz)]
        private static extern unsafe hb_glyph_info_t* hb_buffer_get_glyph_infos(hb_buffer_t buf, ref int glyph_count);
        public static hb_glyph_info_t[] hb_buffer_get_glyph_infos(hb_buffer_t buf)
        {
            unsafe
            {
                int count = 0;
                hb_glyph_info_t* arr = hb_buffer_get_glyph_infos(buf, ref count);
                var outarr = new hb_glyph_info_t[count];
                for (var i = 0; i < count; i++)
                    outarr[i] = arr[i];
                return outarr;
            }
        }

        [DllImport(harfbuzz)]
        private static extern unsafe hb_glyph_position_t* hb_buffer_get_glyph_positions(hb_buffer_t buf, ref int glyph_count);

        public static hb_glyph_position_t[] hb_buffer_get_glyph_positions(hb_buffer_t buf)
        {
            unsafe
            {
                int count = 0;
                hb_glyph_position_t* arr = hb_buffer_get_glyph_positions(buf, ref count);
                var outarr = new hb_glyph_position_t[count];
                for (var i = 0; i < count; i++)
                    outarr[i] = arr[i];
                return outarr;
            }
        }
        //6.Iterate over each glyph.

        //hb_position_t cursor_x = 0;
        //hb_position_t cursor_y = 0;
        //for (unsigned int i = 0; i<glyph_count; i++) {
        //    hb_codepoint_t glyphid = glyph_info[i].codepoint;
        //    hb_position_t x_offset = glyph_pos[i].x_offset;
        //    hb_position_t y_offset = glyph_pos[i].y_offset;
        //    hb_position_t x_advance = glyph_pos[i].x_advance;
        //    hb_position_t y_advance = glyph_pos[i].y_advance;
        //    /* draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset); */
        //    cursor_x += x_advance;
        //    cursor_y += y_advance;
        //}

        //7.Tidy up.
        //hb_buffer_destroy(buf);
        //hb_font_destroy(font);
        //hb_face_destroy(face);
        //hb_blob_destroy(blob);
        [DllImport(harfbuzz)]
        public static extern void hb_buffer_destroy(hb_buffer_t buf);

        [DllImport(harfbuzz)]
        public static extern void hb_font_destroy(hb_font_t buf);

        [DllImport(harfbuzz)]
        public static extern void hb_face_destroy(hb_face_t buf);

        [DllImport(harfbuzz)]
        public static extern void hb_blob_destroy(hb_blob_t buf);


        //add
        [DllImport(harfbuzz)]
        public static extern void hb_buffer_set_content_type(hb_buffer_t buffer, hb_buffer_content_type_t content_type);


        [DllImport(harfbuzz)]
        public static extern void hb_buffer_guess_segment_properties(hb_buffer_t buffer);
    }

}

namespace freetype
{
    public struct FT_Library
    {
        public IntPtr handle;
    }
    public unsafe struct FT_Face
    {
        public FT_FaceRec* handle;
    }
    public enum FT_Render_Mode
    {
        FT_RENDER_MODE_NORMAL = 0,
        FT_RENDER_MODE_LIGHT,
        FT_RENDER_MODE_MONO,
        FT_RENDER_MODE_LCD,
        FT_RENDER_MODE_LCD_V,

        FT_RENDER_MODE_MAX

    }
    public struct load_flags_T
    {
        public int value;

        public static readonly load_flags_T FT_LOAD_DEFAULT = From(0x0);
        public static readonly load_flags_T FT_LOAD_NO_SCALE = From(1 << 0);
        public static readonly load_flags_T FT_LOAD_NO_HINTING = From(1 << 1);
        public static readonly load_flags_T FT_LOAD_RENDER = From(1 << 2);
        public static readonly load_flags_T FT_LOAD_NO_BITMAP = From(1 << 3);
        public static readonly load_flags_T FT_LOAD_VERTICAL_LAYOUT = From(1 << 4);
        public static readonly load_flags_T FT_LOAD_FORCE_AUTOHINT = From(1 << 5);
        public static readonly load_flags_T FT_LOAD_CROP_BITMAP = From(1 << 6);
        public static readonly load_flags_T FT_LOAD_PEDANTIC = From(1 << 7);
        public static readonly load_flags_T FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH = From(1 << 9);
        public static readonly load_flags_T FT_LOAD_NO_RECURSE = From(1 << 10);
        public static readonly load_flags_T FT_LOAD_IGNORE_TRANSFORM = From(1 << 11);
        public static readonly load_flags_T FT_LOAD_MONOCHROME = From(1 << 12);
        public static readonly load_flags_T FT_LOAD_LINEAR_DESIGN = From(1 << 13);
        public static readonly load_flags_T FT_LOAD_NO_AUTOHINT = From(1 << 15);
        /* Bits 16..19 are used by `FT_LOAD_TARGET_' */
        public static readonly load_flags_T FT_LOAD_COLOR = From(1 << 20);

        /* */

        /* used internally only by certain font drivers! */
        public static readonly load_flags_T FT_LOAD_ADVANCE_ONLY = From(1 << 8);
        public static readonly load_flags_T FT_LOAD_SBITS_ONLY = From(1 << 14);
        public static readonly load_flags_T FT_LOAD_TARGET_NORMAL = FT_LOAD_TARGET_((int)FT_Render_Mode.FT_RENDER_MODE_NORMAL);
        public static readonly load_flags_T FT_LOAD_TARGET_LIGHT = FT_LOAD_TARGET_((int)FT_Render_Mode.FT_RENDER_MODE_LIGHT);
        public static readonly load_flags_T FT_LOAD_TARGET_MONO = FT_LOAD_TARGET_((int)FT_Render_Mode.FT_RENDER_MODE_MONO);
        public static readonly load_flags_T FT_LOAD_TARGET_LCD = FT_LOAD_TARGET_((int)FT_Render_Mode.FT_RENDER_MODE_LCD);
        public static readonly load_flags_T FT_LOAD_TARGET_LCD_V = FT_LOAD_TARGET_((int)FT_Render_Mode.FT_RENDER_MODE_LCD_V);

        public void Or(load_flags_T other)
        {
            this.value |= other.value;
        }
        private static load_flags_T From(int x)
        {
            return new load_flags_T()
            {
                value = x
            };
        }
        private static load_flags_T FT_LOAD_TARGET_(int x)
        {
            return new load_flags_T() { value = ((x) & 15) << 16 };
        }
    }


    public struct FT_Bitmap_Size
    {
        public short height;
        public short width;

        public long size;

        public long x_ppem;
        public long y_ppem;

    }
    public struct FT_CharMap
    {
        public IntPtr handle;
    }
    public struct FT_Generic
    {
        public IntPtr data;
        public IntPtr finalizer;
    }
    public struct FT_BBox
    {
        public long xMin, yMin;
        public long xMax, yMax;
    }
    public unsafe struct FT_GlyphSlot
    {
        public FT_GlyphSlotRec* handle;
    }
    public unsafe struct FT_Size
    {
        public IntPtr handle;
    }
    public struct FT_Glyph_Metrics
    {
        public long width;
        public long height;

        public long horiBearingX;
        public long horiBearingY;
        public long horiAdvance;

        public long vertBearingX;
        public long vertBearingY;
        public long vertAdvance;

    }
    public struct FT_GlyphSlotRec
    {
        public FT_Library library;
        public FT_Face face;
        public FT_GlyphSlot next;
        public uint reserved;       /* retained for binary compatibility */
        public FT_Generic generic;

        public FT_Glyph_Metrics metrics;
        public long linearHoriAdvance;
        public long linearVertAdvance;
        public long advance;

        //FT_Glyph_Format format;

        //FT_Bitmap bitmap;
        //FT_Int bitmap_left;
        //FT_Int bitmap_top;

        //FT_Outline outline;

        //FT_UInt num_subglyphs;
        //FT_SubGlyph subglyphs;

        //void* control_data;
        //long control_len;

        //FT_Pos lsb_delta;
        //FT_Pos rsb_delta;

        //void* other;

        //FT_Slot_Internal internal;

    }

    public unsafe struct FT_FaceRec
    {
        public long num_faces;
        public long face_index;

        public long face_flags;
        public long style_flags;

        public long num_glyphs;

        public byte* family_name;
        public byte* style_name;

        public int num_fixed_sizes;
        public FT_Bitmap_Size* available_sizes;

        public int num_charmaps;
        public FT_CharMap* charmaps;

        public FT_Generic generic;

        /*# The following member variables (down to `underline_thickness') */
        /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size    */
        /*# for bitmap fonts.                                              */
        public FT_BBox bbox;

        public ushort units_per_EM;
        public short ascender;
        public short descender;
        public short height;

        public short max_advance_width;
        public short max_advance_height;

        public short underline_position;
        public short underline_thickness;

        public FT_GlyphSlot glyph;
        public FT_Size size;
        public FT_CharMap charmap;

        ///*@private begin */

        //FT_Driver driver;
        //FT_Memory memory;
        //FT_Stream stream;

        //FT_ListRec sizes_list;

        //FT_Generic autohint;   /* face-specific auto-hinter data */
        //void* extensions; /* unused                         */

        //FT_Face_Internal internal;

        /*@private end */

    }
    static public class wrap
    {

        const string freetype = "libfreetype-6";
        [DllImport(freetype)]
        public static extern int FT_Init_FreeType(ref FT_Library alibrary);



        [DllImport(freetype)]
        public static extern int FT_Done_FreeType(FT_Library library);

        [DllImport(freetype)]
        private static extern unsafe int FT_New_Face(FT_Library library, byte* filepathname, Int64 face_index, ref FT_Face aface);


        public static int FT_New_Face(FT_Library library, string filepathname, Int64 face_index, ref FT_Face aface)
        {
            byte[] txt = System.Text.Encoding.UTF8.GetBytes(filepathname);
            unsafe
            {
                fixed (byte* ptr = txt)
                {
                    return FT_New_Face(library, ptr, face_index, ref aface);
                }
            }
        }
        [DllImport(freetype)]
        public static extern int FT_Set_Char_Size(FT_Face face, long char_width, long char_height, uint horz_resolution, uint vert_resolution);



        [DllImport(freetype)]
        public static extern int FT_Load_Glyph(FT_Face face, uint glyph_index, load_flags_T load_flags);
    }
}